function deepClone(obj, weakmap = new WeakMap()) {
    if(!isObj(obj)) {
        return obj
    }
    let newobj = obj.constructor()
    if(!weakmap.has(obj)) {
        weakmap.set(obj, newobj)
    }
    else {
        return obj
    }
    for(let i in obj) {
        newobj[i] = obj[i] instanceof Object ? deepClone(obj[i], weakmap) : obj[i]
    }
    return newobj
}

function isObj(obj) {
    return obj instanceof Object
}

let obj = {
    name:'csc',
    age:18,
    reg:/(?:)/,  
    arr:[1, 2, {
        name:'csc',
        age:18
    }],
    obj2:{
        name:'lyz',
        age:18
    },
    test:null,
    test1:undefined,
    abc:() => {
        return 123
    }
}
obj.obj1 = obj

let newobj = {
    name:'123',
    age:18,
    obj1:{
        key:1
    },
    reg:new RegExp(),
    test:null,
    test1:undefined,
    abc:() => {
        return 123
    }
}
newobj.a = newobj
// let obj2 = JSON.parse(JSON.stringify(newobj))

console.log(deepClone(obj))

// JSON方法实现简易深拷贝方法的局限性
// 1. 不可以拷贝undefined function RegExp等类型
// 2. 会抛弃对象的 constructor，所有的构造函数会指向 Object
// 3. 对象有循环引用，会报错

